package com.small.account.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.common.basis.exception.BusinessException;
import com.common.basis.result.Result;
import com.common.basis.result.ResultSet;
import com.small.account.entity.AuPermission;
import com.small.account.entity.NodeDrop;
import com.small.account.entity.RoleAndPermission;
import com.small.account.entity.enums.AuPermissionGroupsEnum;
import com.small.account.entity.vo.AuPermissionDrop;
import com.small.account.service.IAuPermissionService;
import com.small.account.service.IRoleAndPermissionService;
import lombok.AllArgsConstructor;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.OAuth2Request;
import org.springframework.security.oauth2.provider.TokenRequest;
import org.springframework.security.oauth2.provider.vote.ScopeVoter;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * 权限
 *
 * @author wangguochao
 */
@RestController
@AllArgsConstructor
@RequestMapping("/au-permission")
public class AuPermissionController {
    private final IAuPermissionService iAuPermissionService;
    private final IRoleAndPermissionService iRoleAndPermissionService;

    /**
     * 用户菜单
     */
    @GetMapping("findTree")
    public Result<List<AuPermission>> findTree(OAuth2Authentication authentication,
                                               @RequestParam String scope) {
        OAuth2Request oAuth2Request = authentication.getOAuth2Request();
        Set<String> scopeList = oAuth2Request.getScope();
        if (!scopeList.contains(scope)) {
            throw new BusinessException("没有权限获取该菜单");
        }
        String name = authentication.getName();
        List<AuPermission> list = iAuPermissionService.findTreeByUserName(name, scope);
        return ResultSet.go(list);
    }


    /**
     * 获取权限树
     */
    @GetMapping
    public Result<?> findTreeAll(OAuth2Authentication authentication) {
        String userName = authentication.getName();
        List<AuPermission> tree = iAuPermissionService.findTree(userName);
        return ResultSet.go(tree);
    }


    /**
     * 新增
     */
    @PostMapping()
    public Result<?> post(@RequestBody @Validated AuPermission param) {
        if (param.getPermissionGroups() == AuPermissionGroupsEnum.APP) {
            return ResultSet.error("客户端不能新增");
        }
        String permissionCode = param.getPermissionCode();
        LambdaQueryWrapper<AuPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AuPermission::getPermissionCode, permissionCode);
        int count = iAuPermissionService.count(wrapper);
        if (count > 0) {
            return ResultSet.error("编号重复");
        }
        boolean b = iAuPermissionService.save(param);

        //将新增的按钮或菜单配置给最高管理员
        RoleAndPermission roleAndPermission = new RoleAndPermission();
        roleAndPermission.setRoleId("b2c8b2230178ef6aab4e5b8dcde2160c");
        roleAndPermission.setPermission(param.getId());
        iRoleAndPermissionService.save(roleAndPermission);
        return ResultSet.operation(b);
    }

    /**
     * 修改
     */
    @PutMapping()
    public Result<?> put(@RequestBody @Validated AuPermission param) {
        String permissionCode = param.getPermissionCode();
        LambdaQueryWrapper<AuPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.ne(AuPermission::getId, param.getId());
        wrapper.eq(AuPermission::getPermissionCode, permissionCode);
        int count = iAuPermissionService.count(wrapper);
        if (count > 0) {
            return ResultSet.error("编号重复");
        }
        boolean b = iAuPermissionService.updateById(param);
        return ResultSet.operation(b);
    }

    /**
     * 删除
     */
    @DeleteMapping()
    public Result<?> del(@RequestParam String id) {
        AuPermission byId = iAuPermissionService.getById(id);
        if (byId.getPermissionGroups() == AuPermissionGroupsEnum.APP) {
            throw new BusinessException("不能删除应用");
        }
        boolean b = iAuPermissionService.removeById(id);
        return ResultSet.operation(b);
    }

    /**
     * 获取权限根据角色
     */
    @GetMapping("find-by-role-id")
    public Result<?> findByRoleId(@RequestParam String id) {
        LambdaQueryWrapper<RoleAndPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RoleAndPermission::getRoleId, id);
        List<RoleAndPermission> list = iRoleAndPermissionService.list(wrapper);
        Set<String> set = list.stream().map(RoleAndPermission::getPermission).collect(Collectors.toSet());
        return ResultSet.go(set);
    }

    /**
     * 拖动排序
     *
     * @param param 参数
     */
    @PostMapping("node-drop")
    public Result<?> nodeDrop(@RequestBody AuPermissionDrop param) {
        AuPermission original = param.getOriginal();
        AuPermission target = param.getTarget();
        String id = original.getId();
        String parentId = null;
        int sortNumber = 0;
        //某某之后
        if (param.getNodeDrop() == NodeDrop.after) {
            parentId = target.getParentId();
            original.setSortNumber(target.getSortNumber() + 1);
        } else if (param.getNodeDrop() == NodeDrop.before) {
            parentId = target.getParentId();
            sortNumber = target.getSortNumber() - 1;

        } else if (param.getNodeDrop() == NodeDrop.inner) {
            parentId = target.getId();
        }
        LambdaUpdateWrapper<AuPermission> update = Wrappers.lambdaUpdate();
        update.eq(AuPermission::getId, id)
                .set(AuPermission::getParentId, parentId)
                .set(AuPermission::getSortNumber, sortNumber)
                .set(AuPermission::getSortTime, LocalDateTime.now());
        iAuPermissionService.update(update);
        return ResultSet.success();
    }

}
